
#include "OpenGLQt.h"
#include "OpenGLQtEasy.h"
#include "cm_logprint.h"
#include "zbar.h"

#include <QtWidgets/QLabel>

static char *args[] = { (char*)"OpenGL" };

OpenGLQt::OpenGLQt(int width, int height)
{
	m_width = width;
	m_height = height;
	m_argc = 1;
	m_file = NULL;

	m_qt = new QApplication(m_argc, args);

	m_widget = new QWidget();
	m_widget->resize(m_width, m_height);
    m_widget->show();

    m_widgetEasy = new OpenGLQtEasy(m_width, m_height, m_widget);
    m_camera = new CameraCapture();

    m_normal = new DisplayNormal(m_width, m_height, m_widget);
    m_normal->show();
}

OpenGLQt::~OpenGLQt()
{
	if (m_camera) {
	    m_camera->close();
	    delete m_camera;
	}
	delete m_normal;
}

int OpenGLQt::test_window_gl_easy() {
    LOGD("enter\n");

    m_widgetEasy->show();
    int ret = m_camera->open();
    if (ret < 0) {
        LOGD("Error open camera [%d]\n", ret);
        return -1;
    }
    return 0;
}

int OpenGLQt::create_window(int width, int height)
{
    m_v_widget = new OpenGLQtWidget(m_widget);
	m_widget->resize(width, height);
	m_v_widget->initializeGL();
	m_v_widget->resize(width, height);
	m_v_widget->resizeGL(width, height);
	m_v_widget->show();
	int ret = m_camera->open();
	if (ret < 0) {
	    LOGD("error open camera [%d]\n", ret);
	    return -1;
	}
	
	return 0;
}

int OpenGLQt::show_img() {
    cv::Mat toshow;
    m_camera->getFrame(toshow);
    DetectQRCode(toshow);
    QImage im;
    m_camera->Mat2QImage(toshow, im);
    m_widgetEasy->renderDisplay(im);
    qt_run();
    return 0;
}

int OpenGLQt::show_decode_img() {
    if (!m_decoder) return -1;
    char *buf = NULL;
    int buflen = 0;
    int width = 0, height = 0;
    int ret = m_decoder->decoder(&buf, &buflen, &width, &height);
    if (ret < 0) {
        return -2;
    }
    LOGD("output len [%d] [%d,%d]\n", buflen, width, height);
    QImage image((uchar*)buf, width, height, QImage::Format_RGB32);
    m_widgetEasy->renderDisplay(image);

    qt_run();
    return 0;
}

std::string OpenGLQt::DetectQRCode(cv::Mat &img)
{
    std::string str = "";
    if (img.channels() == 3)
    {
        cvtColor(img, img, cv::COLOR_BGR2GRAY);
    }
    zbar::ImageScanner scanner;
    scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
    zbar::Image imgZbar(img.cols, img.rows, "Y800", (uchar *)img.data,
                        img.cols * img.rows);
    scanner.scan(imgZbar);
    for(zbar::SymbolIterator symbol = imgZbar.symbol_begin();
        symbol != imgZbar.symbol_end(); ++symbol)
    {
        str = symbol->get_data();
        break;
    }
    return str;
}

int OpenGLQt::show_img_normal() {
    cv::Mat toshow;
    m_camera->getFrame(toshow);
    DetectQRCode(toshow);
    QImage im;
    m_camera->Mat2QImage(toshow, im);
    m_normal->showImg(im);
    qt_run();
    return 0;
}

int OpenGLQt::show_yuv() {
    cv::Mat m;
    bool ret = m_camera->getFrame(m);
    if (!ret) return -1;
//    cv::resize(m, m, cv::Size(480, 320), cv::INTER_LINEAR);
    cv::Mat yuv;
    cv::cvtColor(m, yuv, cv::COLOR_BGR2YUV_I420);
//    LOGD("---------- [%d, %d]\n", yuv.rows, yuv.cols);
    m_v_widget->set_data(yuv.data, yuv.rows, yuv.cols);

    QImage im;
    m_camera->Mat2QImage(m, im);
    m_v_widget->set_image(im);
    qt_run();
    return 0;
}

int OpenGLQt::qt_run() {
    m_qt->eventDispatcher();
    m_qt->processEvents();
    return 0;
}

int OpenGLQt::read_file_start(const char* filename)
{
	//Open YUV420P file
#ifdef _WIN32
	fopen_s(&m_file, filename, "rb");
#else
	m_file = fopen(filename, "rb");
#endif
	if (m_file == NULL) {
		LOG("cannot open this file [%s]\n", filename);
		return -1;
	}

    int size = m_width * m_height * 3 / 2;
	unsigned char *buf = new unsigned char[size];
	while(true)
	{
		if (fread(buf, 1, m_width*m_height * 3 / 2, m_file) != m_width*m_height * 3 / 2) {
			// Loop
			fseek(m_file, 0, SEEK_SET);
			fread(buf, 1, m_width*m_height * 3 / 2, m_file);
		}

		m_v_widget->set_data(buf, m_width, m_height);

		m_qt->eventDispatcher();
		m_qt->processEvents();
		sys_sleep(40);
	}
	
	return 0;
}

